/* 
 *   AQ_Player class defines data of each player 
 * in this game. Every player owns a collection 
 * of hand cards(hand_card) and a goal.
 */
import java.io.*;
import java.util.*;

public class AQ_Player implements Serializable
{
	private Vector<AQ_HandCard> hand_card;
	
	private AQ_Element goal_card;
	
	public AQ_Player(AQ_Element g)
	{
		hand_card=new Vector<AQ_HandCard>();
		goal_card=g;
	}
	
	
	public AQ_Player(final BufferedReader input) throws IOException{
		String line;
		hand_card=new Vector<AQ_HandCard>();
		goal_card=null;
		while((line=input.readLine())!=null){
			String[] data=line.split(" ");
			if(data.length<1) throw new IOException("Bad AQ_Player block.");
			else if(data[0].equals("hand")){
				switch(data.length){
					case 1:
					hand_card.add(AQ_HandCard.getUniversalCard());
					break;
					case 2: // Action cards.
					hand_card.add(AQ_HandCard.getActionCard(Byte.parseByte(data[1])));
					break;
					case 5:
					hand_card.add(AQ_HandCard.getElementCard(Byte.parseByte(data[1]), Byte.parseByte(data[2]), Byte.parseByte(data[3]), Byte.parseByte(data[4])));
					break;
					default: throw new IOException("Bad number of arguments of `"+data[0]+"'.");
				}
				hand_card.lastElement().setOwner(this);
			}
			else if(data[0].equals("goal")){
				if(data.length==2) goal_card=new AQ_Element(Byte.parseByte(data[1]));
				else throw new IOException("Bad number of arguments of `"+data[0]+"'.");
			}
			else if(data[0].equals("AQ_Player")){
				if(data.length==2 && data[1].equals("end")) break;
				else throw new IOException("Bad ending of AQ_Player block.");
			}
			else throw new IOException("No such entry `"+data[0]+"'.");
		}
		if(goal_card==null) throw new IOException("No player can exist without a goal.");
	}
	
	public void add(int index, AQ_HandCard c)
	{
		if(c!=null)
		{
			c.setOwner(this);
			hand_card.add(index, c);
		}
	}
	
	public boolean add(AQ_HandCard c)
	{
		if(c!=null)
		{
			c.setOwner(this);
			return hand_card.add(c);
		}
		return false;
	}
	
	public AQ_HandCard card(int index)
	{
		return hand_card.get(index);
	}
	
	public AQ_Element goal()
	{
		return goal_card;
	}
	
	public AQ_HandCard poll(int index)
	{
		return hand_card.remove(index);
	}
	
	public Vector<AQ_HandCard> pollAll()
	{
		Vector<AQ_HandCard> v=hand_card;
		hand_card=new Vector<AQ_HandCard>();
		return v;
	}
	private void readObject(ObjectInputStream input) throws ClassNotFoundException, IOException{
		AQ_Player the_new=new AQ_Player(goal());
		Object x=input.readObject();
		if(x instanceof Vector<?>){
			Vector<?> y=(Vector<?>)x;
			for(int i=0; i<y.size(); i++){
				if(y.get(i) instanceof AQ_HandCard){
					AQ_HandCard z=(AQ_HandCard)y.get(i);
					z.setOwner(this);
					the_new.hand_card.add(z);
				}
				else throw new ClassNotFoundException("The Vector contains other object rather than AQ_HandCard.");
			}
		}
		else throw new ClassNotFoundException("No expected Vector of hand_card.");
		x=input.readObject();
		if(x instanceof AQ_Element) the_new.goal_card=(AQ_Element)x;
		else throw new ClassNotFoundException("No expected AQ_Element for goal_card.");
		hand_card=the_new.hand_card;
		goal_card=the_new.goal_card;
	}
	public void setGoal(final AQ_Element g)
	{
		goal_card=g;
	}
	
	public void GUItoScreen(handPanel panel)
	{
		Card handcard[] =new Card[10];
		Iterator<AQ_HandCard> p=hand_card.iterator();
		String[] s=new String[]{"", ""};
		int n=0;
		//int actionORelement=0;
		for(int i=0; p.hasNext(); i++)
		{
			AQ_HandCard h=p.next();
			if(0<i)
			{
				s[0]+=" | ";
				s[1]+=" | ";
			}
			if(h instanceof AQ_HandCard.ActionCard)
			{
			
				AQ_HandCard.ActionCard a=(AQ_HandCard.ActionCard)h;
				switch(a.action())
				{
					case 1:
						s[0]+="Trade";
						s[1]+="Hands";
						handcard[i]=new Card(i,0,11,0,0,0,0);
						//handcard[i].setActioncard(11);
						panel.add(handcard[i]);
						handcard[i].repaint();
						break;
					case 2:
						s[0]+="Trade";
						s[1]+="Goals";
						handcard[i]=new Card(i,0,9,0,0,0,0);
						//handcard[i].setActioncard(9);
						panel.add(handcard[i]);
						handcard[i].repaint();
						break;
					case 3:
						s[0]+="Move";
						s[1]+="Card";
						handcard[i]=new Card(i,0,10,0,0,0,0);
						//handcard[i].setActioncard(10);
						panel.add(handcard[i]);
						handcard[i].repaint();
						break;
					case 4:
						s[0]+="Rotate";
						s[1]+="Goals ";
						handcard[i]=new Card(i,0,7,0,0,0,0);
						//handcard[i].setActioncard(7);
						panel.add(handcard[i]);
						handcard[i].repaint();
						break;
					case 5:
						s[0]+="Zap ";
						s[1]+="Card";
						handcard[i]=new Card(i,0,12,0,0,0,0);
						//handcard[i].setActioncard(12);
						panel.add(handcard[i]);
						handcard[i].repaint();
						break;
					case 6:
						s[0]+="Shuffle";
						s[1]+=" Hands ";
						handcard[i]=new Card(i,0,8,0,0,0,0);
						//handcard[i].setActioncard(8);
						panel.add(handcard[i]);
						handcard[i].repaint();
						break;
				}
			}
			else if(h instanceof AQ_HandCard.ElementCard)
			{
				AQ_HandCard.ElementCard e=(AQ_HandCard.ElementCard)h;
				//s[0]+=e.upleft().toString()+" "+e.upright().toString();
				//s[1]+=e.downleft().toString()+" "+e.downright().toString();
				handcard[i]=new Card(i,1,0,e.upleft().element,e.upright().element,e.downleft().element,e.downright().element);
				//handcard[i].setElementcard(e.upleft().element,e.upright().element,e.downleft().element,e.downright().element);
				panel.add(handcard[i]);
				handcard[i].repaint();
			}
		}
		//System.out.println(s[0]);
		//System.out.println(s[1]);
	}
	
	public void toScreen()
	{
		Iterator<AQ_HandCard> p=hand_card.iterator();
		String[] s=new String[]{"", ""};
		
		for(int i=0; p.hasNext(); i++)
		{
			AQ_HandCard h=p.next();
			if(0<i)
			{
				s[0]+=" | ";
				s[1]+=" | ";
			}
			if(h instanceof AQ_HandCard.ActionCard)
			{
				AQ_HandCard.ActionCard a=(AQ_HandCard.ActionCard)h;
				switch(a.action())
				{
					case 1:
						s[0]+="Trade";
						s[1]+="Hands";
						break;
					case 2:
						s[0]+="Trade";
						s[1]+="Goals";
						break;
					case 3:
						s[0]+="Move";
						s[1]+="Card";
						break;
					case 4:
						s[0]+="Rotate";
						s[1]+="Goals ";
						break;
					case 5:
						s[0]+="Zap ";
						s[1]+="Card";
						break;
					case 6:
						s[0]+="Shuffle";
						s[1]+=" Hands ";
						break;
				}
			}
			else if(h instanceof AQ_HandCard.ElementCard)
			{
				AQ_HandCard.ElementCard e=(AQ_HandCard.ElementCard)h;
				s[0]+=e.upleft().toString()+" "+e.upright().toString();
				s[1]+=e.downleft().toString()+" "+e.downright().toString();
			}
		}
		System.out.println(s[0]);
		System.out.println(s[1]);
	}
	
	public void tradeGoal(AQ_Player another)
	{
		AQ_Element tmp=goal_card;
		goal_card=another.goal_card;
		another.goal_card=tmp;
	}
	
	public void tradeHands(AQ_Player another)
	{
		Vector<AQ_HandCard> tmp=hand_card;
		hand_card=another.hand_card;
		another.hand_card=tmp;
		
		for(Iterator<AQ_HandCard> p=hand_card.iterator(); p.hasNext(); ) 
			p.next().setOwner(this);
		
		for(Iterator<AQ_HandCard> p=another.hand_card.iterator(); p.hasNext(); ) 
			p.next().setOwner(another);
	}
	private void writeObject(ObjectOutputStream output) throws IOException{
		output.writeObject(hand_card);
		output.writeObject(goal_card);
	}
}
